package com.uzhie.media.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.uzhie.exception.MonitorException;
import com.uzhie.jt808.util.DateUtil;
import com.uzhie.media.MediaChannelHandlerContextHolder;
import com.uzhie.media.MediaConstant;
import com.uzhie.media.spring.MsgIDMapping;
import com.uzhie.media.spring.MsgService;
import com.uzhie.web.module.Vehicle;
import com.uzhie.web.service.MonitoringService;
import com.uzhie.web.service.PlayBackService;
import com.uzhie.web.service.VehicleService;
import com.uzhie.util.CacheManager;
import io.netty.channel.Channel;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;

/**
 * Created by TangFei on 2018/7/28.
 */
@MsgService
public class MediaRequestServiceImpl extends MediaService implements MediaRequestService {

    private Logger logger = Logger.getLogger(getClass());

    @Autowired(required = false)
    private CacheManager<String, Channel> cacheManager;

    @Autowired(required = false)
    private CacheManager<String, JSON> jsonCacheManager;

    @Autowired(required = false)
    private VehicleService vehicleService;

    @Autowired(required = false)
    private MonitoringService monitoringService;

    @Autowired(required = false)
    private PlayBackService playBackService;

    /**
     * 1.2 流媒体服务器心跳
     *
     * @param msgID 消息ID
     * @param body  消息体
     * @return
     */
    @MsgIDMapping(msgID = MediaConstant.MSG_ID.MEDIA_REQ_HEART_BEAT)
    @Override
    public JSONObject hearBeat(int msgID, JSONObject body) {
        logger.debug("心跳处理 " + body + "\t" + MediaChannelHandlerContextHolder.getContextThreadLocal());
        cacheManager.put(CacheManager.DES.MEDIA_SESSION_CACHE, "mediaTCPSession", MediaChannelHandlerContextHolder.getContextThreadLocal().channel());
        return response(STATUS.OK, null);
    }

    /**
     * 2.5 查询直播通道数（流媒体服务器响应的请求）
     *
     * @param msgID
     * @param body
     * @return
     */
    @MsgIDMapping(msgID = MediaConstant.MSG_ID.PLA_REQ_ONLINE_CHANNEL)
    public JSONObject onLineDevNum(int msgID, JSONObject body) {
        logger.info("流媒体响应平台直播在线通道数请求：" + body);
        jsonCacheManager.put(CacheManager.DES.SYS_CACHE, body.getJSONObject("result").getJSONObject("data").getString("simNo"), body);
        return response(STATUS.OK, null);
    }

    /**
     * 2.10 查询指定播放类型在线连接数 （流媒体服务器响应的请求）
     *
     * @param msgID
     * @param body
     * @return
     */
    @MsgIDMapping(msgID = MediaConstant.MSG_ID.PLA_REQ_CHANNEL_TYPE_NUMBER)
    public JSONObject channelTypeNum(int msgID, JSONObject body) {
        logger.info("指定播放类型在线连接数：" + body);
        jsonCacheManager.put(CacheManager.DES.SYS_CACHE, "_channelTypeNum", body);
        return response(STATUS.OK, null);
    }

    /**
     * 2.1 上级平台时效性验证
     *
     * @param msgID 消息ID
     * @param body  消息体
     * @return
     */
    @MsgIDMapping(msgID = MediaConstant.MSG_ID.MEDIA_REQ_TIME_CODE)
    @Override
    public JSONObject govTimeCodeValidate(int msgID, JSONObject body) {
        logger.info("上级平台时效性验证：" + body);
        JSONObject data = new JSONObject();
        data.put("valid", 1);
        return response(STATUS.OK, data);
    }

    /**
     * 2.2 车辆信息是否在线验证
     *
     * @param msgID 消息ID
     * @param body  消息体
     * @return
     */
    @MsgIDMapping(msgID = MediaConstant.MSG_ID.MEDIA_REQ_VEHICLE_INFO)
    @Override
    public JSONObject onLineVehicleInfo(int msgID, JSONObject body) {
        logger.info("车辆信息是否在线验证：" + body);
        Vehicle vehicleNo = vehicleService.selectByNumber(body.getString("vehicleNo"));
        JSONObject data = new JSONObject();
        try {
            data.put("isOnline", true);
            data.put("type", vehicleNo.getType());
            data.put("deviceId", vehicleNo.getDeviceNumber());
            data.put("status", vehicleNo.getStatus());
            data.put("vehicleNo", body.getString("vehicleNo"));
            data.put("simNo", vehicleNo.getSimNumber());
        } catch (RuntimeException e) {
            data.put("isOnline", false);
            data.put("type", "null");
            data.put("deviceId", "null");
            data.put("status", "null");
            data.put("vehicleNo", body.getString("vehicleNo"));
            data.put("simNo", "null");
        } finally {
            return response(STATUS.OK, data);
        }
    }

    /**
     * 2.3 获取视频自动断开时长
     *
     * @param msgID 消息ID
     * @param body  消息体
     * @return
     */
    @MsgIDMapping(msgID = MediaConstant.MSG_ID.MEDIA_REQ_VIDEO_LIVE_TIME)
    @Override
    public JSONObject videoLiveTime(int msgID, JSONObject body) {
        logger.info("获取视频自动断开时长：" + body);
        JSONObject data = new JSONObject();
        data.put("duration", 5);
        return response(STATUS.OK, data);
    }

    /**
     * 2.4 媒体存储
     *
     * @param msgID 消息ID
     * @param body  消息体
     * @return
     */
    @MsgIDMapping(msgID = MediaConstant.MSG_ID.MEDIA_REQ_VIDEO_SAVE)
    @Override
    public JSONObject videoSave(int msgID, JSONObject body) {
        logger.info("流媒体服务器视频存储：" + body);
        try {
            monitoringService.addVideo(body);
            return response(STATUS.OK, null);
        } catch (RuntimeException e) {
            logger.error(e);
            return response(STATUS.ERROR, "null");
        }
    }

    /**
     * 2.7 发送指令给终端
     *
     * @param msgID 消息ID
     * @param body  消息体
     * @return
     */
    @MsgIDMapping(msgID = MediaConstant.MSG_ID.MEDIA_REQ_POST_DEV)
    @Override
    public JSONObject postDev(int msgID, JSONObject body) {
        logger.info("流媒体请求平台发送指令给终端：" + body);
        Integer playType = body.getInteger("playType");
        int result = 1;
        String msg = "null";
        switch (playType) {
            case 1:
                // 直播
                // TODO: 2018/8/12 码流暂时为0
                try {
                    msg = monitoringService.controlOrder(body.getString("simNo"), body.getInteger("channelNumber"), body.getInteger("controlType"), 0, 0);
                    result = 0;
                } catch (MonitorException e) {
                    msg = e.getMessage();
                    logger.error(e);
                }
                break;
            case 2:
                // 复播
                try {
                    msg = playBackService.playBackControl(body.getString("simNo"), body.getInteger("channelNumber"), body.getInteger("controlType"), 0, DateUtil.dateToString(new Date()));
                    result = 0;
                } catch (MonitorException e) {
                    msg = e.getMessage();
                    logger.error(e);
                }
                break;
            default:
                logger.error("播放类型错误！");
                break;
        }
        JSONObject data = new JSONObject();
        data.put("result", result);
        data.put("message", msg);
        return response(STATUS.OK, data);
    }

    /**
     * 2.6 更新前端的播放状态保持
     */
    @MsgIDMapping(msgID = MediaConstant.MSG_ID.PLA_REQ_PLAY_STATUS_KEEP)
    public void playKeep(int msgID, JSONObject body) {
        logger.info("收到流媒体2.6请求：" + body);
    }
}
